package com.snack.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.snack.shop.common.BusinessException;
import com.snack.shop.common.OrderStatus;
import com.snack.shop.common.OrderType;
import com.snack.shop.dto.CreatePickupOrderParam;
import com.snack.shop.entity.ErrandOrder;
import com.snack.shop.entity.Order;
import com.snack.shop.entity.PickupCategory;
import com.snack.shop.entity.User;
import com.snack.shop.mapper.ErrandOrderMapper;
import com.snack.shop.mapper.OrderMapper;
import com.snack.shop.mapper.PickupCategoryMapper;
import com.snack.shop.mapper.UserMapper;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.snack.shop.service.FileManageService;
import com.snack.shop.service.PickupOrderService;
import com.snack.shop.service.SystemConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 代取订单服务实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class PickupOrderServiceImpl implements PickupOrderService {

    private final OrderMapper orderMapper;
    private final ErrandOrderMapper errandOrderMapper;
    private final PickupCategoryMapper pickupCategoryMapper;
    private final UserMapper userMapper;
    private final FileManageService fileManageService;
    private final ObjectMapper objectMapper;
    private final SystemConfigService systemConfigService;

    // 平台服务费率改为从系统配置读取（pickup_platform_fee_rate，单位：百分比0-100）

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createOrder(CreatePickupOrderParam param, Long userId) {
        // 1. 获取分类信息
        PickupCategory category = pickupCategoryMapper.selectById(param.getCategoryId());
        if (category == null || category.getStatus() != 1) {
            throw new BusinessException("分类不存在或已禁用");
        }

        // 2. 校验服务费不低于基础价格
        if (param.getServiceFee().compareTo(category.getBasePrice()) < 0) {
            throw new BusinessException("服务费用不能低于基础价格");
        }

        // 3. 计算平台服务费和接单方收益
        BigDecimal platformFeeRatePercent = systemConfigService.getConfigValueAsDecimal("pickup_platform_fee_rate", new BigDecimal("25.00"));
        if (platformFeeRatePercent == null) {
            platformFeeRatePercent = new BigDecimal("25.00");
        }
        BigDecimal platformFee = param.getServiceFee()
                .multiply(platformFeeRatePercent)
                .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
        BigDecimal riderEarning = param.getServiceFee().subtract(platformFee);

        // 4. 创建主订单
        Order order = new Order();
        order.setOrderNo(generateOrderNo());
        order.setUserId(userId);
        order.setOrderType(category.getServiceType()); // 2-取快递，3-取外卖，4-代取奶咖
        order.setStatus(0); // 待支付
        order.setTotalAmount(param.getServiceFee());
        order.setActualAmount(param.getServiceFee());
        order.setDeliveryAddress(param.getDeliveryAddress());
        
        // 结算相关
        order.setSettlementStatus(0); // 未结算
        order.setPlatformFee(platformFee);
        order.setPlatformFeeRate(platformFeeRatePercent);
        order.setRiderEarning(riderEarning);

        orderMapper.insert(order);

        // 5. 创建跑腿订单详情
        ErrandOrder errandOrder = new ErrandOrder();
        errandOrder.setOrderId(order.getId());
        errandOrder.setServiceType(category.getServiceType());
        errandOrder.setCategoryId(param.getCategoryId());
        errandOrder.setPickupAddress(param.getPickupAddress());
        errandOrder.setPickupCode(param.getPickupCode());
        errandOrder.setPickupRemark(param.getPickupRemark());
        errandOrder.setFirstImage(param.getFirstImage());
        errandOrder.setSecondImage(param.getSecondImage());
        errandOrder.setDeliveryAddress(param.getDeliveryAddress());
        errandOrder.setReceiverName(param.getReceiverName());
        errandOrder.setReceiverPhone(param.getReceiverPhone());
        errandOrder.setDeliveryRemark(param.getDeliveryRemark());

        errandOrderMapper.insert(errandOrder);

        return order.getId();
    }

    @Override
    public Page<Map<String, Object>> getOrderPage(String role, Integer status, Integer settlementStatus, Long userId, Integer current, Integer size) {
        Page<Order> page = new Page<>(current, size);
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        
        // 只查询代取订单（order_type = 2/3/4/5）
        wrapper.in(Order::getOrderType, 2, 3, 4, 5);
        
        if ("publisher".equals(role)) {
            // 发布方：查询自己发布的订单
            wrapper.eq(Order::getUserId, userId);
        } else if ("taker".equals(role)) {
            // 接单方：查询自己接单的订单
            wrapper.eq(Order::getDeliveryUserId, userId);
        } else if ("merchant".equals(role)) {
            // 商家：查询所有代取订单（不加用户限制）
            // 商家作为平台管理者，可以查看所有代取订单
        }
        
        if (status != null) {
            wrapper.eq(Order::getStatus, status);
        }
        
        if (settlementStatus != null) {
            wrapper.eq(Order::getSettlementStatus, settlementStatus);
            
            // 商家查询结算订单时，需要包含已退款但有补偿金的订单
            if ("merchant".equals(role) && (settlementStatus == 1 || settlementStatus == 2)) {
                // 移除之前的status限制，重新设置查询条件
                wrapper.clear();
                wrapper.in(Order::getOrderType, 2, 3, 4, 5)
                       .eq(Order::getSettlementStatus, settlementStatus);
                
                if (settlementStatus == 1) {
                    // 待结算：status=5 或 (status=8 且有补偿金)
                    wrapper.and(w -> w.eq(Order::getStatus, 5)
                        .or(subWrapper -> subWrapper.eq(Order::getStatus, 8)
                            .isNotNull(Order::getCompensationAmount)
                            .gt(Order::getCompensationAmount, BigDecimal.ZERO)));
                } else if (settlementStatus == 2) {
                    // 已结算：status=6 或 (status=8 且有补偿金)
                    wrapper.and(w -> w.eq(Order::getStatus, 6)
                        .or(subWrapper -> subWrapper.eq(Order::getStatus, 8)
                            .isNotNull(Order::getCompensationAmount)
                            .gt(Order::getCompensationAmount, BigDecimal.ZERO)));
                }
            }
        }
        
        wrapper.orderByDesc(Order::getCreateTime);
        
        Page<Order> orderPage = orderMapper.selectPage(page, wrapper);
        
        // 组装订单详情
        Page<Map<String, Object>> resultPage = new Page<>(current, size);
        resultPage.setTotal(orderPage.getTotal());
        resultPage.setRecords(orderPage.getRecords().stream().map(this::buildOrderMap).collect(Collectors.toList()));
        
        return resultPage;
    }

    @Override
    public Page<Map<String, Object>> getAvailableOrders(Long categoryId, Integer current, Integer size) {
        Page<Order> page = new Page<>(current, size);
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        
        // 待接单状态
        wrapper.eq(Order::getStatus, 1);
        wrapper.in(Order::getOrderType, 2, 3, 4, 5);
        
        if (categoryId != null) {
            // 需要关联 errand_order 表过滤
            wrapper.exists("SELECT 1 FROM t_errand_order e WHERE e.order_id = t_order.id AND e.category_id = " + categoryId);
        }
        
        wrapper.orderByDesc(Order::getCreateTime);
        
        Page<Order> orderPage = orderMapper.selectPage(page, wrapper);
        
        Page<Map<String, Object>> resultPage = new Page<>(current, size);
        resultPage.setTotal(orderPage.getTotal());
        resultPage.setRecords(orderPage.getRecords().stream().map(this::buildOrderMap).collect(Collectors.toList()));
        
        return resultPage;
    }

    @Override
    public Map<String, Object> getOrderDetail(Long orderId) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        return buildOrderMap(order);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void acceptOrder(Long orderId, Long userId) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        if (order.getStatus() != 1) {
            throw new BusinessException("订单状态不正确，无法接单");
        }
        
        // 检查是否是自己的订单
        if (order.getUserId().equals(userId)) {
            throw new BusinessException("不能接自己发布的订单");
        }
        
        // 更新订单状态
        order.setStatus(2); // 待取件
        order.setDeliveryUserId(userId);
        order.setAcceptTime(LocalDateTime.now());
        orderMapper.updateById(order);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmPickup(Long orderId, Long userId, String pickupImages) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        if (!order.getDeliveryUserId().equals(userId)) {
            throw new BusinessException("无权操作此订单");
        }
        
        if (order.getStatus() != 2) {
            throw new BusinessException("订单状态不正确");
        }
        
        // 更新订单状态
        order.setStatus(3); // 配送中
        orderMapper.updateById(order);
        
        // 更新跑腿订单详情
        LambdaQueryWrapper<ErrandOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ErrandOrder::getOrderId, orderId);
        ErrandOrder errandOrder = errandOrderMapper.selectOne(wrapper);
        if (errandOrder != null) {
            errandOrder.setPickupImages(pickupImages);
            errandOrder.setPickupTime(LocalDateTime.now());
            errandOrderMapper.updateById(errandOrder);
        }
        
        // ✅ 立即确认取件照片为正式状态
        try {
            if (pickupImages != null && !pickupImages.trim().isEmpty()) {
                List<String> imageUrls = parseImageUrls(pickupImages);
                if (!imageUrls.isEmpty()) {
                    fileManageService.confirmFiles(imageUrls, "order", orderId);
                    log.info("确认取件照片为正式状态: orderId={}, imageCount={}", orderId, imageUrls.size());
                }
            }
        } catch (Exception e) {
            log.error("确认取件照片失败: orderId={}", orderId, e);
            // 不影响主流程
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmDeliver(Long orderId, Long userId, String deliveryImages) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        if (!order.getDeliveryUserId().equals(userId)) {
            throw new BusinessException("无权操作此订单");
        }
        
        if (order.getStatus() != 3) {
            throw new BusinessException("订单状态不正确");
        }
        
        // 更新订单状态
        order.setStatus(4); // 已送达
        orderMapper.updateById(order);
        
        // 更新跑腿订单详情
        LambdaQueryWrapper<ErrandOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ErrandOrder::getOrderId, orderId);
        ErrandOrder errandOrder = errandOrderMapper.selectOne(wrapper);
        if (errandOrder != null) {
            errandOrder.setDeliveryImages(deliveryImages);
            errandOrder.setDeliveryTime(LocalDateTime.now());
            errandOrderMapper.updateById(errandOrder);
        }
        
        // ✅ 立即确认送达照片为正式状态
        try {
            if (deliveryImages != null && !deliveryImages.trim().isEmpty()) {
                List<String> imageUrls = parseImageUrls(deliveryImages);
                if (!imageUrls.isEmpty()) {
                    fileManageService.confirmFiles(imageUrls, "order", orderId);
                    log.info("确认送达照片为正式状态: orderId={}, imageCount={}", orderId, imageUrls.size());
                }
            }
        } catch (Exception e) {
            log.error("确认送达照片失败: orderId={}", orderId, e);
            // 不影响主流程
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmReceive(Long orderId, Long userId) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        if (!order.getUserId().equals(userId)) {
            throw new BusinessException("无权操作此订单");
        }
        
        if (order.getStatus() != 4) {
            throw new BusinessException("订单状态不正确");
        }
        
        // 更新订单状态
        order.setStatus(5); // 待结算
        order.setSettlementStatus(0); // 未结算（明确设置，等待商家结算）
        order.setConfirmTime(LocalDateTime.now());
        orderMapper.updateById(order);
        
        // ✅ 确认订单关联的所有图片为正式状态
        confirmOrderImages(order);
    }
    
    /**
     * 确认订单关联的所有图片
     */
    private void confirmOrderImages(Order order) {
        try {
            List<String> imageUrls = new ArrayList<>();
            
            // 获取跑腿订单详情
            LambdaQueryWrapper<ErrandOrder> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ErrandOrder::getOrderId, order.getId());
            ErrandOrder errandOrder = errandOrderMapper.selectOne(wrapper);
            
            if (errandOrder != null) {
                // 收集第一张图片
                if (errandOrder.getFirstImage() != null) {
                    imageUrls.addAll(parseImageUrls(errandOrder.getFirstImage()));
                }
                
                // 收集第二张图片
                if (errandOrder.getSecondImage() != null) {
                    imageUrls.addAll(parseImageUrls(errandOrder.getSecondImage()));
                }
                
                // 收集取件照片
                if (errandOrder.getPickupImages() != null) {
                    imageUrls.addAll(parseImageUrls(errandOrder.getPickupImages()));
                }
                
                // 收集送达照片
                if (errandOrder.getDeliveryImages() != null) {
                    imageUrls.addAll(parseImageUrls(errandOrder.getDeliveryImages()));
                }
            }
            
            // 确认所有图片
            if (!imageUrls.isEmpty()) {
                fileManageService.confirmFiles(imageUrls, "order", order.getId());
                log.info("确认订单图片为正式状态: orderId={}, imageCount={}", order.getId(), imageUrls.size());
            }
        } catch (Exception e) {
            log.error("确认订单图片失败: orderId={}", order.getId(), e);
            // 不影响主流程
        }
    }
    
    /**
     * 解析图片URL（支持JSON数组格式和逗号分隔格式）
     */
    private List<String> parseImageUrls(String imagesStr) {
        if (imagesStr == null || imagesStr.trim().isEmpty()) {
            return new ArrayList<>();
        }
        
        try {
            // 尝试解析JSON数组格式：["url1", "url2"]
            List<String> urls = objectMapper.readValue(imagesStr, new TypeReference<List<String>>() {});
            return urls.stream()
                    .filter(url -> url != null && !url.trim().isEmpty())
                    .collect(Collectors.toList());
        } catch (Exception e) {
            // 兼容逗号分隔格式：url1,url2
            List<String> urls = new ArrayList<>();
            for (String url : imagesStr.split(",")) {
                String trimmed = url.trim();
                if (!trimmed.isEmpty()) {
                    urls.add(trimmed);
                }
            }
            return urls;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelOrder(Long orderId, Long userId, String reason) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        if (!order.getUserId().equals(userId)) {
            throw new BusinessException("无权操作此订单");
        }
        
        if (order.getStatus() > 2) {
            throw new BusinessException("订单已进入配送流程，无法取消");
        }
        
        // 更新订单状态
        order.setStatus(7); // 已取消
        order.setCancelReason(reason);
        orderMapper.updateById(order);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int autoConfirmDeliveredOrders(LocalDateTime deadline) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getStatus, OrderStatus.DELIVERED)
               .in(Order::getOrderType, OrderType.EXPRESS, OrderType.TAKEOUT, OrderType.COFFEE, 5)
               .lt(Order::getUpdateTime, deadline);
        List<Order> deliveredOrders = orderMapper.selectList(wrapper);
        if (deliveredOrders == null || deliveredOrders.isEmpty()) {
            return 0;
        }

        LocalDateTime now = LocalDateTime.now();
        int count = 0;
        for (Order order : deliveredOrders) {
            order.setStatus(OrderStatus.WAIT_SETTLEMENT);
            order.setSettlementStatus(0);
            order.setConfirmTime(now);
            orderMapper.updateById(order);
            confirmOrderImages(order);
            count++;
        }
        log.info("自动确认收货并进入待结算的代取订单数量={}，deadline={}", count, deadline);
        return count;
    }

    /**
     * 生成订单号
     */
    private String generateOrderNo() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String timeStr = LocalDateTime.now().format(formatter);
        long random = (long) (Math.random() * 900000) + 100000; // 6位随机数
        return "PU" + timeStr + random;
    }

    /**
     * 构建订单Map
     */
    private Map<String, Object> buildOrderMap(Order order) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", order.getId());
        map.put("orderNo", order.getOrderNo());
        map.put("userId", order.getUserId());
        map.put("orderType", order.getOrderType());
        map.put("status", order.getStatus());
        map.put("statusText", getStatusText(order.getStatus()));
        map.put("totalAmount", order.getTotalAmount());
        map.put("actualAmount", order.getActualAmount());
        map.put("platformFee", order.getPlatformFee());
        map.put("platformFeeRate", order.getPlatformFeeRate());
        map.put("riderEarning", order.getRiderEarning());
        map.put("settlementStatus", order.getSettlementStatus());
        
        // 退款相关字段
        map.put("refundStatus", order.getRefundStatus());
        map.put("refundAmount", order.getRefundAmount());
        map.put("compensationAmount", order.getCompensationAmount());
        map.put("refundApplyTime", order.getRefundApplyTime());
        map.put("refundRejectReason", order.getRefundRejectReason());
        map.put("cancelReason", order.getCancelReason());
        map.put("createTime", order.getCreateTime());
        map.put("payTime", order.getPayTime());
        map.put("acceptTime", order.getAcceptTime());
        map.put("confirmTime", order.getConfirmTime());
        map.put("finishTime", order.getFinishTime());
        
        // 查询发布人信息
        if (order.getUserId() != null) {
            User publisher = userMapper.selectById(order.getUserId());
            if (publisher != null) {
                map.put("userName", publisher.getNickname());
                map.put("userPhone", publisher.getPhone());
            }
        }
        
        // 查询接单人信息（如果有）
        if (order.getDeliveryUserId() != null) {
            User taker = userMapper.selectById(order.getDeliveryUserId());
            if (taker != null) {
                map.put("deliveryUserName", taker.getNickname());
                map.put("deliveryUserPhone", taker.getPhone());
                map.put("takerName", taker.getNickname()); // 兼容前端两种命名
                map.put("takerPhone", taker.getPhone());
            }
        }
        
        // 查询跑腿订单详情
        LambdaQueryWrapper<ErrandOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ErrandOrder::getOrderId, order.getId());
        ErrandOrder errandOrder = errandOrderMapper.selectOne(wrapper);
        if (errandOrder != null) {
            map.put("categoryId", errandOrder.getCategoryId());
            map.put("pickupAddress", errandOrder.getPickupAddress());
            map.put("pickupCode", errandOrder.getPickupCode());
            map.put("pickupRemark", errandOrder.getPickupRemark());
            map.put("deliveryAddress", errandOrder.getDeliveryAddress());
            map.put("receiverName", errandOrder.getReceiverName());
            map.put("receiverPhone", errandOrder.getReceiverPhone());
            map.put("deliveryRemark", errandOrder.getDeliveryRemark());
            map.put("pickupImages", errandOrder.getPickupImages());
            map.put("deliveryImages", errandOrder.getDeliveryImages());
            map.put("firstImage", errandOrder.getFirstImage());
            map.put("secondImage", errandOrder.getSecondImage());
            map.put("pickupTime", errandOrder.getPickupTime());
            map.put("deliveryTime", errandOrder.getDeliveryTime());
            
            // 获取分类名称和服务类型
            if (errandOrder.getCategoryId() != null) {
                PickupCategory category = pickupCategoryMapper.selectById(errandOrder.getCategoryId());
                if (category != null) {
                    map.put("categoryName", category.getName());
                    map.put("serviceType", category.getServiceType());
                }
            }
        }
        
        return map;
    }

    /**
     * 获取状态文本
     */
    private String getStatusText(Integer status) {
        switch (status) {
            case 0: return "待支付";
            case 1: return "待接单";
            case 2: return "待取件";
            case 3: return "配送中";
            case 4: return "已送达";
            case 5: return "待结算";
            case 6: return "已完成";
            case 7: return "已取消";
            case 8: return "已退款";
            default: return "未知状态";
        }
    }
}

